package com.swiot.quartz.task;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.swiot.biz.domain.AlertRecord;
import com.swiot.biz.domain.TemplateData;
import com.swiot.biz.service.IAlertRecordService;
import com.swiot.biz.service.IRuleService;
import com.swiot.biz.service.ITemplateDataService;
import com.swiot.common.core.domain.entity.SysDept;
import com.swiot.common.core.redis.RedisCache;
import com.swiot.common.utils.DateUtils;
import com.swiot.common.utils.StringUtils;
import com.swiot.quartz.domain.RuleMessage;
import com.swiot.quartz.util.ValueUtils;
import com.swiot.system.service.ISysDeptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;

/**
 * 定时任务调度测试
 *
 * @author SuGuichuan
 */
@Component("alarmTask")
public class AlarmTask {
    private static final Logger log = LoggerFactory.getLogger(AlarmTask.class);

    @Resource
    IRuleService ruleService;
    @Resource
    ITemplateDataService templateDataService;
    @Resource
    IAlertRecordService alertRecordService;
    @Autowired
    private RedisCache redisCache;
    @Resource
    private ISysDeptService sysDeptService;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    /**
     * 推送告警
     *
     * @param templateDataId
     */
    public void pushAlarm(String templateDataId) {
        TemplateData templateData = templateDataService.selectTemplateDataSimpleById(templateDataId);
        if (templateData == null) {
            return;
        }
        JSONObject fieldObject = JSONObject.parseObject(templateData.getFieldObject());
        if (fieldObject == null) {
            return;
        }
        Integer count = alertRecordService.selectAlertRecordCountById(templateDataId);
        if (count > 0) {
            count = alertRecordService.deleteAlertRecordByTemplateDataId(templateDataId);
            log.info("删除告警记录数量：{}", count);
        }
        SysDept sysDept = sysDeptService.selectDeptById(templateData.getDeptId());
        if (sysDept != null) {
            templateData.setDeptName(sysDept.getDeptName());
            templateData.setSegmentName(sysDept.getSegmentName());
        }
//        System.out.println("执行告警方法：" + templateData.getFieldObject());
        for (String key : fieldObject.keySet()) {
            JSONObject field = fieldObject.getJSONObject(key);

            if (field == null || field.isEmpty() || !field.containsKey("value") || !field.containsKey("alarm")) {
                log.warn("字段对象为空");
                continue;
            }
            String value = field.getString("value");
            String alarm = field.getString("alarm");
//            log.info("字段对象 {}:{}", key, value);

            JSONObject ruleCache = ruleService.getRuleCache();
            if (ruleCache == null || ruleCache.isEmpty()) {
                log.warn("告警规则缓存为空");
                continue;
            }

            RuleMessage ruleMessage = RuleMessage.builder(templateData, key, field, ruleCache);
            // 执行告警方法
            try {

                Method method = getClass().getMethod(ruleMessage.getRuleFunc(), RuleMessage.class);
                String result = (String) method.invoke(this, ruleMessage);

                log.info("执行成功：{}：执行结果：{}，执行数据：{}", key, result, ruleMessage.toString());
            } catch (Exception e) {
                log.info("执行异常：{}：执行数据：{}，异常信息：{}", key, ruleMessage.toString(), e.toString());

            }
        }


    }


    /**
     * 检查范围值告警方法
     *
     * @param ruleMessage 告警参数
     * @return
     */
    public String checkRangeValue(RuleMessage ruleMessage) {

        try {
            log.info("检查checkRangeValue范围值告警方法参数：{}", ruleMessage.toString());
            if (ruleMessage == null) {
                return "error";
            }
            String fieldName = ruleMessage.getFieldName();
            String year = DateUtils.getYear();
            String lastYear = Integer.parseInt(year) - 1 + "";
            HashMap<String, Object> range = templateDataService.queryTemplateDataSum(ruleMessage.getTemplateData().getId(), year);
            HashMap<String, Object> lastRange = templateDataService.queryTemplateDataSum(ruleMessage.getTemplateData().getId(), lastYear);
            JSONArray params = JSONArray.parseArray(ruleMessage.getRuleParam());
            //最小参数值
            BigDecimal minParam = new BigDecimal(params.get(0).toString());
            //最大参数值
            BigDecimal maxParam = new BigDecimal(params.get(1).toString());

            // 当前值
            BigDecimal currVal = new BigDecimal(ruleMessage.getValue());
            if (params == null || params.isEmpty()) {
                return "error";
            }
            if (params.size() != 2) {
                return "error";
            }


            if (range != null) {
                Object fieldValue = range.get(fieldName);
                if (fieldValue == null) {
                    return "error";
                }
                // 当年历史累计值
                BigDecimal fieldVal = new BigDecimal(fieldValue.toString());
                //比对当前值除以历史值，获取百分比
                int percent = ValueUtils.comparePercent(fieldVal.toString(), currVal.toString());

                //结果百分比值与参数最小值比
                if (percent >= minParam.intValue()) {
                    insertAlarmRecord(ruleMessage.getTemplateData(), ruleMessage.getRuleId(), 1L, ruleMessage.getFieldName(), ruleMessage.getFieldName(), "当前值：" + currVal + "，当年历史累计值：" + fieldVal + "，超出范围" + percent + "%");
                } else {
                    log.info("percent-minParam：{}:{}", percent, minParam);
                }
                if (percent >= maxParam.intValue()) {
                    insertAlarmRecord(ruleMessage.getTemplateData(), ruleMessage.getRuleId(), 2L, ruleMessage.getFieldName(), ruleMessage.getFieldName(), "当前值：" + currVal + "，当年历史累计值：" + fieldVal + "，超出范围" + percent + "%");
                } else {
                    log.info("percent-maxParam：{}:{}", percent, maxParam);
                }
            }

            if (lastRange != null) {
                Object lastFieldValue = lastRange.get(fieldName);
                if (lastFieldValue == null) {
                    return "error";
                }
                //上一年历史累计值
                BigDecimal lastFieldVal = new BigDecimal(lastFieldValue.toString());
                //比对当前值除以上一年历史累计值，获取百分比
                int lastYearPercent = ValueUtils.comparePercent(lastFieldVal.toString(), currVal.toString());
                if (lastYearPercent >= minParam.intValue()) {
                    insertAlarmRecord(ruleMessage.getTemplateData(), ruleMessage.getRuleId(), 1L, ruleMessage.getFieldName(), ruleMessage.getFieldName(), "当前值：" + currVal + "，上一年历史累计值：" + lastFieldVal + "，超出范围" + lastYearPercent + "%");
                } else {
                    log.info("lastYearPercent-minParam：{}:{}", lastYearPercent, minParam);
                }
                if (lastYearPercent >= maxParam.intValue()) {
                    insertAlarmRecord(ruleMessage.getTemplateData(), ruleMessage.getRuleId(), 2L, ruleMessage.getFieldName(), ruleMessage.getFieldName(), "当前值：" + currVal + "，上一年历史累计值：" + lastFieldVal + "，超出范围" + lastYearPercent + "%");
                } else {
                    log.info("lastYearPercent-maxParam：{}:{}", lastYearPercent, maxParam);
                }
            }


            log.info("range：{}", range);
            log.info("lastRange：{}", lastRange);
        } catch (Exception e) {
            log.error("检查checkRangeValue范围值告警方法参数错误：{}", ruleMessage.toString());
            e.printStackTrace();
            return "error";
        }
        return "success";
    }

    /**
     * 检查范围百分比告警方法
     *
     * @param ruleMessage 告警参数
     * @return
     */
    public String checkRangePercent(RuleMessage ruleMessage) {
//        System.out.println("checkRangePercent告警方法");
        try {

            log.info("检查checkRangePercent范围值告警方法参数：{}", ruleMessage.toString());
        } catch (Exception e) {
            log.error("检查checkRangePercent范围值告警方法参数错误：{}", ruleMessage.toString());
            return "error";
        }
        return "error";
    }

    private void insertAlarmRecord(TemplateData data,String ruleId, Long alarmLevel, String alertKey, String alertKeyName, String alertContent) {
        AlertRecord alertRecord = new AlertRecord();
        alertRecord.setDeptId(data.getDeptId());
        alertRecord.setDeptName(data.getDeptName());
        alertRecord.setTemplateId(data.getTemplateId());
        alertRecord.setTemplateName(data.getTemplateName());
        alertRecord.setReportDate(data.getReportDate());
        alertRecord.setSegmentName(data.getSegmentName());
        alertRecord.setTemplateDataId(data.getId());
        alertRecord.setRuleId(ruleId);
        alertRecord.setAlertKey(alertKey);
        alertRecord.setAlertKeyName(alertKeyName);
        alertRecord.setAlertContent(alertContent);
        alertRecord.setAlertTime(DateUtils.getNowDate());
        alertRecord.setAlertLevel(alarmLevel);
        alertRecord.setDelFlag("0");
        alertRecord.setStatus(1L);
        alertRecord.setCreateTime(DateUtils.getNowDate());

        int result = alertRecordService.insertAlertRecord(alertRecord);
        if (result > 0) {
            log.info("插入告警记录成功：{}", alertRecord.toString());
        } else {
            log.info("插入告警记录失败：{}", alertRecord.toString());
        }
    }
}
